/**
 * ...
 * @author Krzysztof Rozalski
 */

package hapi.remoting;
import haxe.remoting.AsyncConnection;

class AsyncConnectionMethodMock implements AsyncConnection {
	
	var service:Dynamic;
	var method:Dynamic->Dynamic;
	var methodName:String;
	var onError:Dynamic->Void;
	var delayInMillis:Int;
	
	public function new(name:String, method:Dynamic->Dynamic, service:Dynamic, delayInMillis:Int) {
		this.method = method;
		this.service = service;
		this.methodName = name;
		this.delayInMillis = delayInMillis;
	}
	
	public function resolve( name : String ) : AsyncConnection {
		throw "Cannnot resolve " + name + " on AsyncConnectionMethodMock";
		return null;
	}
	
	public function call( params : Array<Dynamic>, ?callOnResult : Dynamic -> Void ) : Void {
		var result = null;
		var f = createCallback(params, callOnResult);
		haxe.Timer.delay(f, delayInMillis);
		//try {
			//result = Reflect.callMethod( service, method, params );
		//}catch (e:Dynamic) {
			//callOnError(e, params);
		//}
		//if (callOnResult != null) {
			//callOnResult(result);
		//}
	}
	
	public function setErrorHandler( onError : Dynamic -> Void ) : Void {
		this.onError = onError;
	}
	
	private function callOnError(cause:Dynamic, params:Array<Dynamic>) {
		var serviceName = "";
		if (service != null) {
			serviceName = Type.getClassName(Type.getClass(service)) + ".";
		}
		onError({message:"Method invocation error "+serviceName+methodName + "(" + params+")", cause:cause});
	}
	
	private function createCallback( params, callOnResult ) {
		var me = this;
		var result = null;
		return function() { 
			try {
				result = Reflect.callMethod(  me.service,  me.method, params );
			}catch (e:Dynamic) {
				me.callOnError(e, params);
			}
			if (callOnResult != null) {
				callOnResult(result);
			}
		};
	}
}